// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable CommentTypo
// ReSharper disable IdentifierTypo
// ReSharper disable InconsistentNaming
// ReSharper disable StringLiteralTypo
// ReSharper disable UnusedParameter.Local

/*
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

using AM.Reporting.Utils;
using AM.Reporting.Barcode;

#endregion

#nullable enable

namespace AM.Reporting.Import.DevExpress
{
    /// <summary>
    /// The DevExpress units converter.
    /// </summary>
    public static class UnitsConverter
    {
        public static float Ratio = 1;

        #region Public Methods

        /// <summary>
        /// Converts SizeF to pixels.
        /// </summary>
        /// <param name="str">SizeF value as string.</param>
        /// <returns>The value in pixels.</returns>
        public static float SizeFToPixels (string str)
        {
            var value = 0.0f;
            if (!string.IsNullOrEmpty (str))
            {
                var end = str.IndexOf ("F");
                if (end > -1)
                {
                    value = Convert.ToSingle (str.Substring (0, end), CultureInfo.InvariantCulture);
                }
                else
                {
                    value = Convert.ToSingle (str, CultureInfo.InvariantCulture);
                }
            }

            return value / Ratio;
        }

        /// <summary>
        /// Converts SizeF to pixels.
        /// </summary>
        /// <param name="str">SizeF value as string.</param>
        /// <returns>The value in pixels.</returns>
        /// <remarks>
        /// Use this method for fonts, because font size is not stored as multiplied by dpi
        /// </remarks>
        public static float SizeFToPixelsFont (string str)
        {
            return SizeFToPixels (str) * Ratio;
        }

        /// <summary>
        /// Converts value to Boolean.
        /// </summary>
        /// <param name="str">Boolen value as string.</param>
        public static bool ConvertBool (string str)
        {
            return str.ToLower() == "true";
        }

        /// <summary>
        /// Converts DevExpress Color.
        /// </summary>
        /// <param name="str">The DevExpress Color value as string.</param>
        /// <returns>The Color value.</returns>
        public static Color ConvertColor (string str)
        {
            if (!string.IsNullOrEmpty (str))
            {
                if (str.IndexOf ("FromArgb") > -1)
                {
                    var start = str.IndexOf ("byte") + 6;
                    var red = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    start = str.IndexOf ("byte", start) + 6;
                    var green = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    start = str.IndexOf ("byte", start) + 6;
                    var blue = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    return Color.FromArgb (red, green, blue);
                }
                else if (str.Split (',').Length == 4)
                {
                    string[] colors = str.Split (',');
                    var alpha = Convert.ToInt32 (colors[0]);
                    var red = Convert.ToInt32 (colors[1]);
                    var green = Convert.ToInt32 (colors[2]);
                    var blue = Convert.ToInt32 (colors[3]);
                    return Color.FromArgb (alpha, red, green, blue);
                }
                else
                {
                    return Color.FromName (str.Replace ("System.Drawing.Color.", ""));
                }
            }

            return Color.Black;
        }

        /// <summary>
        /// Converts DevExpress BackColor.
        /// </summary>
        /// <param name="str">The DevExpress BackColor value as string.</param>
        /// <returns>The Color value.</returns>
        public static Color ConvertBackColor (string str)
        {
            if (!string.IsNullOrEmpty (str))
            {
                if (str.IndexOf ("FromArgb") > -1)
                {
                    var start = str.IndexOf ("byte") + 6;
                    var red = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    start = str.IndexOf ("byte", start) + 6;
                    var green = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    start = str.IndexOf ("byte", start) + 6;
                    var blue = Convert.ToInt32 (str.Substring (start, str.IndexOf (")", start) - start));
                    return Color.FromArgb (red, green, blue);
                }
                else if (str.Split (',').Length == 4)
                {
                    string[] colors = str.Split (',');
                    var alpha = Convert.ToInt32 (colors[0]);
                    var red = Convert.ToInt32 (colors[1]);
                    var green = Convert.ToInt32 (colors[2]);
                    var blue = Convert.ToInt32 (colors[3]);
                    return Color.FromArgb (alpha, red, green, blue);
                }
                else
                {
                    return Color.FromName (str.Replace ("System.Drawing.Color.", ""));
                }
            }

            return Color.Transparent;
        }

        /// <summary>
        /// Converts the DevExpress BorderDashStyle to LineStyle.
        /// </summary>
        /// <param name="borderDashStyle">The DevExpress BorderDashStyle value.</param>
        /// <returns>The LineStyle value.</returns>
        public static LineStyle ConvertBorderDashStyle (string borderDashStyle)
        {
            if (borderDashStyle is "DevExpress.XtraPrinting.BorderDashStyle.Dot" or "Dot")
            {
                return LineStyle.Dot;
            }
            else if (borderDashStyle is "DevExpress.XtraPrinting.BorderDashStyle.Dash" or "Dash")
            {
                return LineStyle.Dash;
            }
            else if (borderDashStyle is "DevExpress.XtraPrinting.BorderDashStyle.DashDot" or "DashDot")
            {
                return LineStyle.DashDot;
            }
            else if (borderDashStyle is "DevExpress.XtraPrinting.BorderDashStyle.DashDotDot" or "DashDotDot")
            {
                return LineStyle.DashDotDot;
            }
            else if (borderDashStyle is "DevExpress.XtraPrinting.BorderDashStyle.Double" or "Double")
            {
                return LineStyle.Double;
            }

            return LineStyle.Solid;
        }

        /// <summary>
        /// Converts the DevExpress LineStyle to LineStyle.
        /// </summary>
        /// <param name="lineStyle">The DevExpress LineStyle value.</param>
        /// <returns>The LineStyle value.</returns>
        public static LineStyle ConvertLineStyle (string lineStyle)
        {
            if (lineStyle == "System.Drawing.Drawing2D.DashStyle.Dot")
            {
                return LineStyle.Dot;
            }
            else if (lineStyle == "System.Drawing.Drawing2D.DashStyle.Dash")
            {
                return LineStyle.Dash;
            }
            else if (lineStyle == "System.Drawing.Drawing2D.DashStyle.DashDot")
            {
                return LineStyle.DashDot;
            }
            else if (lineStyle == "System.Drawing.Drawing2D.DashStyle.DashDotDot")
            {
                return LineStyle.DashDotDot;
            }
            else if (lineStyle == "System.Drawing.Drawing2D.DashStyle.Double")
            {
                return LineStyle.Double;
            }

            return LineStyle.Solid;
        }

        /// <summary>
        /// Converts the DevExpress TextAlignment to HorzAlignment.
        /// </summary>
        /// <param name="textAlignment">The DevExpress TextAlignment value.</param>
        /// <returns>The HorzAlign value.</returns>
        public static HorizontalAlign ConvertTextAlignmentToHorzAlign (string textAlignment)
        {
            if (textAlignment.Contains ("Center"))
            {
                return HorizontalAlign.Center;
            }

            if (textAlignment.Contains ("Justify"))
            {
                return HorizontalAlign.Justify;
            }

            if (textAlignment.Contains ("Right"))
            {
                return HorizontalAlign.Right;
            }

            return HorizontalAlign.Left;
        }

        /// <summary>
        /// Converts the DevExpress TextAlignment to VertAlignment.
        /// </summary>
        /// <param name="textAlignment">The DevExpress TextAlignment value.</param>
        /// <returns>The VertAlign value.</returns>
        public static VerticalAlign ConvertTextAlignmentToVertAlign (string textAlignment)
        {
            if (textAlignment.Contains ("Middle"))
            {
                return VerticalAlign.Center;
            }

            if (textAlignment.Contains ("Bottom"))
            {
                return VerticalAlign.Bottom;
            }

            return VerticalAlign.Top;
        }

        /// <summary>
        /// Converts the DevExpress ImageSizeMode to PictureBoxSizeMode.
        /// </summary>
        /// <param name="sizeMode">The ImageSizeMode value as string.</param>
        /// <returns>The PictureBoxSizeMode value.</returns>
        public static PictureBoxSizeMode ConvertImageSizeMode (string sizeMode)
        {
            if (sizeMode is "DevExpress.XtraPrinting.ImageSizeMode.StretchImage" or "StretchImage")
            {
                return PictureBoxSizeMode.StretchImage;
            }
            else if (sizeMode is "DevExpress.XtraPrinting.ImageSizeMode.AutoSize" or "AutoSize")
            {
                return PictureBoxSizeMode.AutoSize;
            }
            else if (sizeMode is "DevExpress.XtraPrinting.ImageSizeMode.CenterImage" or "CenterImage")
            {
                return PictureBoxSizeMode.CenterImage;
            }
            else if (sizeMode is "DevExpress.XtraPrinting.ImageSizeMode.ZoomImage" or "ZoomImage")
            {
                return PictureBoxSizeMode.Zoom;
            }
            else if (sizeMode is "DevExpress.XtraPrinting.ImageSizeMode.Squeeze" or "Squeeze")
            {
                return PictureBoxSizeMode.Zoom;
            }

            return PictureBoxSizeMode.Normal;
        }

        internal static ImageAlign ConvertImageAlignment (string alignment)
        {
            var align = ImageAlign.None;
            switch (alignment)
            {
                case "TopCenter":
                    return ImageAlign.Top_Center;
                case "TopLeft":
                    return ImageAlign.Top_Left;
                case "TopRight":
                    return ImageAlign.Top_Right;
                case "CenterLeft":
                    return ImageAlign.Center_Left;
                case "CenterCenter":
                    return ImageAlign.Center_Center;
                case "CenterRight":
                    return ImageAlign.Center_Right;
                case "BottomLeft":
                    return ImageAlign.Bottom_Left;
                case "BottomCenter":
                    return ImageAlign.Bottom_Center;
                case "BottomRight":
                    return ImageAlign.Bottom_Right;
            }

            return align;
        }

        /// <summary>
        /// Converts the DevExpress Shape to ShapeKind.
        /// </summary>
        /// <param name="shape">The DevExpress Shape value as string.</param>
        /// <returns>The ShapeKind value.</returns>
        public static ShapeKind ConvertShape (string shape)
        {
            if (shape.Contains ("Rectangle"))
            {
                return ShapeKind.Rectangle;
            }
            else if (shape.Contains ("Polygon"))
            {
                return ShapeKind.Triangle;
            }

            return ShapeKind.Ellipse;
        }

        /// <summary>
        /// Converts the DevExpress Barcode.Symbology to Barcode.Barcode.
        /// </summary>
        /// <param name="symbology">The DevExpress Barcode.Symbology value as string.</param>
        /// <param name="barcode">The BarcodeObject instance.</param>
        public static void ConvertBarcodeSymbology (string symbology, BarcodeObject barcode)
        {
            symbology = symbology.ToLower();
            if (symbology.Contains ("codabar"))
            {
                barcode.Barcode = new BarcodeCodabar();
            }
            else if (symbology.Contains ("code128"))
            {
                barcode.Barcode = new Barcode128();
            }
            else if (symbology.Contains ("code39"))
            {
                barcode.Barcode = new Barcode39();
            }
            else if (symbology.Contains ("code39extended"))
            {
                barcode.Barcode = new Barcode39Extended();
            }
            else if (symbology.Contains ("code93"))
            {
                barcode.Barcode = new Barcode93();
            }
            else if (symbology.Contains ("code9eextended"))
            {
                barcode.Barcode = new Barcode93Extended();
            }
            else if (symbology.Contains ("codemsi"))
            {
                barcode.Barcode = new BarcodeMSI();
            }
            else if (symbology.Contains ("datamatrix"))
            {
                barcode.Barcode = new BarcodeDatamatrix();
            }
            else if (symbology.Contains ("ean128"))
            {
                barcode.Barcode = new BarcodeEAN128();
            }
            else if (symbology.Contains ("ean13"))
            {
                barcode.Barcode = new BarcodeEAN13();
            }
            else if (symbology.Contains ("ean8"))
            {
                barcode.Barcode = new BarcodeEAN8();
            }
            else if (symbology.Contains ("industrial2of5"))
            {
                barcode.Barcode = new Barcode2of5Industrial();
            }
            else if (symbology.Contains ("interleaved2of5"))
            {
                barcode.Barcode = new Barcode2of5Interleaved();
            }
            else if (symbology.Contains ("matrix2of5"))
            {
                barcode.Barcode = new Barcode2of5Matrix();
            }
            else if (symbology.Contains ("pdf417"))
            {
                barcode.Barcode = new BarcodePDF417();
            }
            else if (symbology.Contains ("postnet"))
            {
                barcode.Barcode = new BarcodePostNet();
            }
            else if (symbology.Contains ("qrcode"))
            {
                barcode.Barcode = new BarcodeQR();
            }
            else if (symbology.Contains ("upca"))
            {
                barcode.Barcode = new BarcodeUPC_A();
            }
            else if (symbology.Contains ("upce0"))
            {
                barcode.Barcode = new BarcodeUPC_E0();
            }
            else if (symbology.Contains ("upce1"))
            {
                barcode.Barcode = new BarcodeUPC_E1();
            }
            else if (symbology.Contains ("upcsupplemental2"))
            {
                barcode.Barcode = new BarcodeSupplement2();
            }
            else if (symbology.Contains ("upcsupplemental5"))
            {
                barcode.Barcode = new BarcodeSupplement5();
            }
        }

        /// <summary>
        /// Converts the DevExpress border sides to AM.Reporting border sides
        /// </summary>
        /// <param name="sides">The DevExpress Barcode.Symbology value as string.</param>
        /// <param name="border">The BarcodeObject instance.</param>
        public static BorderLines ConvertBorderSides (string sides, Border border)
        {
            var borderLines = BorderLines.None;
            if (!string.IsNullOrEmpty (sides))
            {
                if (sides.IndexOf ("Left") > -1)
                {
                    borderLines |= BorderLines.Left;
                }

                if (sides.IndexOf ("Top") > -1)
                {
                    borderLines |= BorderLines.Top;
                }

                if (sides.IndexOf ("Right") > -1)
                {
                    borderLines |= BorderLines.Right;
                }

                if (sides.IndexOf ("Bottom") > -1)
                {
                    borderLines |= BorderLines.Bottom;
                }

                if (sides.IndexOf ("All") > -1)
                {
                    borderLines = BorderLines.All;
                }
            }

            return borderLines;
        }

        #endregion // Public Methods
    }
}
